package com.bdbit.ChargingStation.device;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttMessage;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
public class ChargingDevice {

    // 设备信息
    private final String iccid;
    private final String imei;

    // 设备状态
    private volatile boolean isPoweredOn = false;
    private volatile boolean isCharging = false;
    private volatile int currentPower = 0;
    private volatile long chargingTimeLeft = 0;

    // MQTT客户端
    private MqttClient mqttClient;

    // 定时任务调度器
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);

    public ChargingDevice(String iccid, String imei) {
        this.iccid = iccid;
        this.imei = imei;
    }

    // 上电初始化
    public void powerOn() {
        this.isPoweredOn = true;
        sendRegistration();
        startHeartbeat();
    }

    // 断电关闭
    public void powerOff() {
        this.isPoweredOn = false;
        this.isCharging = false;
        scheduler.shutdownNow();
        try {
            if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
                log.warn("定时任务未完全终止");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    // 发送注册包
    private void sendRegistration() {
        MqttMessage message = new MqttMessage(iccid.getBytes());
        sendMessage(iccid, message);
    }

    // 启动心跳 - 优化版
    private void startHeartbeat() {
        scheduler.scheduleAtFixedRate(() -> {
            if (isPoweredOn) {
                MqttMessage message = new MqttMessage(iccid.getBytes());
                sendMessage(iccid, message);
                log.debug("发送心跳包: {}", iccid);
            }
        }, 0, 5, TimeUnit.SECONDS);
    }

    // 处理来自系统的消息
    public void processSystemMessage(MqttMessage message) {
        String payload = new String(message.getPayload());
        // 格式: ICCID.金额.充电时长(分钟)
        if (payload.startsWith(iccid)) {
            startChargingSequence(payload);
        }
    }

    // 启动充电序列
    private void startChargingSequence(String payload) {
        String[] parts = payload.split("\\.");
        if (parts.length < 3) return;

        int amount = Integer.parseInt(parts[1]);
        int minutes = Integer.parseInt(parts[2]);

        // 转换为毫秒
        chargingTimeLeft = minutes * 60 * 1000L;

        // 打开供电端口
        powerOnChargingPort();

        // 启动功率检测
        startPowerMonitoring();
    }

    // 打开供电端口
    private void powerOnChargingPort() {
        log.info("打开供电端口");
        isCharging = true;
    }

    // 启动功率监控
    private void startPowerMonitoring() {
        scheduler.schedule(() -> {
            int power = measurePower();
            long startTime = System.currentTimeMillis();

            while (System.currentTimeMillis() - startTime < 30000 && isCharging) {
                power = measurePower();

                if (power > 1800) {
                    handleOverload();
                    return;
                } else if (power < 5) {
                    handleNoLoad();
                    return;
                }

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    return;
                }
            }

            // 30秒后功率正常，开始充电
            if (isCharging) {
                startCharging(power);
            }
        }, 0, TimeUnit.MILLISECONDS);
    }

    // 开始充电
    private void startCharging(int initialPower) {
        log.info("开始正常充电，初始功率: {}W", initialPower);
        currentPower = initialPower;

        // 发送充电开始通知
        String message = String.format("%s.charing.%d", iccid, chargingTimeLeft / 60000);
        sendMessage(imei, new MqttMessage(message.getBytes()));

        // 启动充电定时器
        startChargingTimer();

        // 启动功率监控
        startPowerMonitoringDuringCharging();
    }

    // 启动充电定时器 - 优化版
    private void startChargingTimer() {
        // 每分钟发送一次状态更新
        scheduler.scheduleAtFixedRate(() -> {
            if (isCharging && chargingTimeLeft > 0) {
                // 每分钟减少1分钟
                chargingTimeLeft -= 60000;

                // 发送状态更新
                String message = String.format("%s.charing.%d", iccid, chargingTimeLeft / 60000);
                sendMessage(imei, new MqttMessage(message.getBytes()));

                // 充电完成
                if (chargingTimeLeft <= 0) {
                    handleChargingDone();
                }
            }
        }, 0, 1, TimeUnit.MINUTES);
    }

    // 充电过程中监控功率
    private void startPowerMonitoringDuringCharging() {
        scheduler.scheduleAtFixedRate(() -> {
            if (!isCharging) return;

            int current = measurePower();
            int previous = currentPower;
            currentPower = current;

            // 功率超过1800W
            if (current > 1800) {
                handleOverload();
                return;
            }

            // 功率掉到几乎为0（考虑设备误差）
            if (current < 5 && previous > 30) {
                handlePowerDropped();
            }

            // 功率上升超过50W
            if (current - previous > 50) {
                handlePowerIncreased(previous, current);
            }
        }, 0, 1, TimeUnit.SECONDS);
    }

    // 处理过载
    private void handleOverload() {
        log.warn("检测到过载，切断电源");
        String message = String.format("%s.overload", iccid);
        sendMessage(imei, new MqttMessage(message.getBytes()));
        cutOffPower();
    }

    // 处理无负载
    private void handleNoLoad() {
        log.warn("检测到无负载，切断电源");
        String message = String.format("%s.NoLoad", iccid);
        sendMessage(imei, new MqttMessage(message.getBytes()));
        cutOffPower();
    }

    // 处理功率突降
    private void handlePowerDropped() {
        log.warn("检测到功率突降，启动60秒恢复计时");
        scheduler.schedule(() -> {
            if (isCharging && measurePower() < 30) {
                String message = String.format("%s.errordone", iccid);
                sendMessage(imei, new MqttMessage(message.getBytes()));
                cutOffPower();
            }
        }, 60, TimeUnit.SECONDS);
    }

    // 处理功率突增
    private void handlePowerIncreased(int previous, int current) {
        log.warn("检测到功率突增 ({}W -> {}W)，停止供电", previous, current);
        String message = String.format("%s.changed", iccid);
        sendMessage(imei, new MqttMessage(message.getBytes()));
        stopPowerSupply();
    }

    // 处理充电完成
    private void handleChargingDone() {
        log.info("充电完成");
        String message = String.format("%s.done", iccid);
        sendMessage(imei, new MqttMessage(message.getBytes()));
        cutOffPower();
    }

    // 测量功率 (模拟)
    private int measurePower() {
        // 实际硬件实现
        return (int) (Math.random() * 2000);
    }

    // 切断电源
    private void cutOffPower() {
        log.info("切断电源");
        isCharging = false;
        // 实际硬件操作
    }

    // 停止供电
    private void stopPowerSupply() {
        log.info("停止供电");
        isCharging = false;
        // 实际硬件操作
    }

    // 发送消息
    private void sendMessage(String topic, MqttMessage message) {
        try {
            if (mqttClient != null && mqttClient.isConnected()) {
                mqttClient.publish(topic, message);
                log.debug("消息已发送 | 主题: {}, 内容: {}", topic, new String(message.getPayload()));
            }
        } catch (Exception e) {
            log.error("发送消息失败", e);
        }
    }
}